#ifndef _PROC_H_
#define _PROC_H_

#include "../../include/types.h"
#include "spinlock.h"
#include "../mm/vm.h"
#include "exec.h"
#include "../file/fs.h"
#include "spinlock.h"
#include "../mm/pmm.h"
#include "../boot/printf.h"
#include "../../include/riscv.h"
#include "../../include/memlayout.h"
#include "../trap/trap.h"
#include "../file/file.h"
#include "../file/string.h"
// 内核栈计算：每个进程的内核栈在虚拟地址空间高地址
#define KSTACK(p) (TRAPFRAME - ((p)+1)* 2*PGSIZE)

// 进程表大小
#define NPROC 64   // 最大进程数
#define NCPU 1     // CPU核心数（单核）

// 文件系统相关（暂不实现，先定义）
#define NOFILE 16  // 每个进程最大打开文件数
#define NFILE 100  // 系统最大打开文件数
#define NINODE 50  // 最大inode数
#define NDEV 10    // 最大设备号

// 进程状态枚举
enum procstate {
  UNUSED,    // 未使用
  USED,      // 已分配但未初始化
  SLEEPING,  // 睡眠中
  RUNNABLE,  // 可运行
  RUNNING,   // 运行中
  ZOMBIE     // 僵尸（等待父进程回收）
};

// 上下文切换时保存的寄存器（callee-saved）
struct context {
  uint64 ra;    // 返回地址
  uint64 sp;    // 栈指针
  // callee-saved registers
  uint64 s0;
  uint64 s1;
  uint64 s2;
  uint64 s3;
  uint64 s4;
  uint64 s5;
  uint64 s6;
  uint64 s7;
  uint64 s8;
  uint64 s9;
  uint64 s10;
  uint64 s11;
};

// CPU结构体（单核简化版）
struct cpu {
  struct proc *proc;          // 当前运行的进程
  struct context context;     // 内核调度器上下文
  int noff;                   // push_off嵌套计数
  int intena;                 // 进入临界区前的中断状态
  int last_proc_idx;          // 上次调度的进程索引（用于轮转调度）
};

// 陷阱帧（用于保存用户态上下文，暂不实现用户态）
struct trapframe {
  /*  0 */ uint64 kernel_satp;   // 内核页表
  /*  8 */ uint64 kernel_sp;     // 内核栈顶
  /* 16 */ uint64 kernel_trap;   // trap处理函数
  /* 24 */ uint64 epc;           // 程序计数器
  /* 32 */ uint64 kernel_hartid; // CPU核心ID
  /* 40 */ uint64 ra;
  /* 48 */ uint64 sp;
  /* 56 */ uint64 gp;
  /* 64 */ uint64 tp;
  /* 72 */ uint64 t0;
  /* 80 */ uint64 t1;
  /* 88 */ uint64 t2;
  /* 96 */ uint64 s0;
  /*104 */ uint64 s1;
  /*112 */ uint64 a0;
  /*120 */ uint64 a1;
  /*128 */ uint64 a2;
  /*136 */ uint64 a3;
  /*144 */ uint64 a4;
  /*152 */ uint64 a5;
  /*160 */ uint64 a6;
  /*168 */ uint64 a7;
  /*176 */ uint64 s2;
  /*184 */ uint64 s3;
  /*192 */ uint64 s4;
  /*200 */ uint64 s5;
  /*208 */ uint64 s6;
  /*216 */ uint64 s7;
  /*224 */ uint64 s8;
  /*232 */ uint64 s9;
  /*240 */ uint64 s10;
  /*248 */ uint64 s11;
  /*256 */ uint64 t3;
  /*264 */ uint64 t4;
  /*272 */ uint64 t5;
  /*280 */ uint64 t6;
};



// 进程结构体
struct proc {
  spinlock lock;       // 保护进程结构的锁
  
  enum procstate state;        // 进程状态
  void *chan;                  // 等待通道（用于sleep/wakeup）
  int killed;                  // 是否被杀死
  int xstate;                  // 退出状态码
  int pid;                     // 进程ID
  
  struct proc *parent;         // 父进程指针
  
  struct trapframe *trapframe; // 陷阱帧
  struct context context;      // 内核上下文
  uint64 kstack;               // 内核栈虚拟地址
  
  uint64 sz;                   // 进程内存大小（字节）
  pagetable_t pagetable;       // 页表指针
  
  char name[16];               // 进程名称（调试用）
  
  // 文件系统（暂不实现）
  struct inode *cwd;                     // 当前目录inode
  struct file *ofile[NOFILE];  // 打开的文件
};

// 全局变量声明
extern struct cpu cpus[NCPU];
extern struct proc proc[NPROC];
extern struct proc *initproc;

// 函数声明
void procinit(void);
void userinit(void);
void proc_mapstacks(pagetable_t kpgtbl);
struct proc* allocproc(void);
void freeproc(struct proc *p);
pagetable_t proc_pagetable(struct proc *p);
void proc_freepagetable(pagetable_t pagetable, uint64 sz);
struct proc* myproc(void);
void forkret(void);

// 汇编函数
void swtch(struct context *old, struct context *new);

// 辅助函数
int uvmcopy(pagetable_t old, pagetable_t new, uint64 sz);
void reparent(struct proc *p);
void wakeup(void *chan);
void sleep(void *chan, spinlock *lk);
void sched(void);
void yield(void);
void scheduler(void);
void test_process_creation(void);
// 进程管理函数
int fork(void);
void exit(int status);
int wait(uint64 addr);

// 内存复制函数
int copyout(pagetable_t pagetable, uint64 dstva, void *src, uint64 len);

// 进程kill相关函数
void setkilled(struct proc *p);
int killed(struct proc *p);

// 创建任务进程
struct proc* create_task_process(void (*task_func)(void));

// 进程创建和等待的封装函数
int create_process(void (*task_func)(void));
int wait_process(uint64 addr);

// 测试相关函数
void simple_task(void);
void test_process_creation(void);
void test_userProcess(void);

int
either_copyin(void *dst, int user_src, uint64 src, uint64 len);

int
either_copyout(int user_dst, uint64 dst, void *src, uint64 len);


// 同步机制相关函数
void shared_buffer_init(void);
void wait_semaphore(int *sem);
void signal_semaphore(int *sem);
void producer_task(void);
void consumer_task(void);
void test_synchronization(void);

#endif
